package com.asiainfo.ai.mirror.util;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;


/***
 * linux脚本运行
 * 
 * @author xiaopu
 *
 */

public class ExecScript {

	private static final Logger log = LoggerFactory.getLogger(ExecScript.class);
	public static String run(String command) throws IOException {
		Scanner input = null;
		Process process = null;
		String result = "";
		try {
			log.info("ExecScript-------->run----------->{}:{}", command);
			process = Runtime.getRuntime().exec(command);

			try {
				// 标准输入流（必须写在 waitFor 之前）
				//			    String inStr = consumeInputStream(process.getInputStream());

				//			    log.info("ExecScript-------->run----------->InputStream:{}",inStr);
				// 标准错误流（必须写在 waitFor 之前）
				//			    String errStr = consumeInputStream(process.getErrorStream());
				//			    log.info("ExecScript-------->run----------->ErrorStream:{}",errStr);
				// 获取进程的标准输入流
				InputStream is1 = process.getInputStream();
				// 获取进城的错误流
				InputStream is2 = process.getErrorStream();

				new Thread() {
					public void run() {
						BufferedReader br1 = new BufferedReader(new InputStreamReader(is1));
						try {
							String line1 = null;
							while ((line1 = br1.readLine()) != null) {
								if (line1 != null) {
									log.info("ExecScript-------->run----------->InputStream:{}", line1);
								}
							}
						}
						catch (IOException e) {
							log.info("ExecScript-------->run----------->InputStream ERROR:", e);
						}
						finally {
							try {
								is1.close();
							}
							catch (IOException e) {
								log.info("ExecScript-------->run----------->ErrorStream ERROR:", e);
							}
						}
					}
				}.start();

				new Thread() {
					public void run() {
						BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));
						try {
							String line2;
							while ((line2 = br2.readLine()) != null) {
								//fixbug: [PRDAI_ISSUE_721] 问题修复：已知为非空值的冗余nullcheck
								if (StringUtils.isNotBlank(line2)) {
									log.info("ExecScript-------->run----------->ErrorStream:{}", line2);
								}
							}
						}
						catch (IOException e) {
							log.info("ExecScript-------->run----------->ErrorStream ERROR:", e);
						}
						finally {
							try {
								is2.close();
							}
							catch (IOException e) {
								log.info("ExecScript-------->run----------->ErrorStream ERROR:", e);
							}
						}
					}
				}.start();

				// 等待命令执行完成
				process.waitFor();
			}
			catch (InterruptedException e) {
				log.info("ExecScript-------->run----------->异常:", e);
				return "";
			}
			InputStream is = process.getInputStream();
			input = new Scanner(is);
			while (input.hasNextLine()) {
				result += input.nextLine() + "\n";
			}
			result = command + "\n" + result; // 加上命令本身，打印出来
			log.info("ExecScript-------->run----------->SH执行结果:{}", result);
		}
		finally {
			if (input != null) {
				input.close();
			}
			if (process != null) {
				process.destroy();
			}
		}
		return result;
	}

	/**
	 * 消费inputstream，并返回
	 * 
	 * @throws IOException
	 */
	public static String consumeInputStream(InputStream is) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String s;
		StringBuilder sb = new StringBuilder();
		while ((s = br.readLine()) != null) {
			//			System.out.println(s);
			sb.append(s);
		}
		return sb.toString();
	}

	public static String run(String command, long timeOut) throws IOException {
		log.info("ExecScript-------->run----------->{}:{}", command, timeOut);
		Scanner input = null;
		String result = "";
		Process process = null;
		try {
			process = Runtime.getRuntime().exec(command);
			try {
				// 等待命令执行完成
				process.waitFor(timeOut, TimeUnit.SECONDS);
			}
			catch (InterruptedException e) {
				log.info("ExecScript-------->run----------->异常:", e);
				return "";
			}
			InputStream is = process.getInputStream();
			input = new Scanner(is);
			while (input.hasNextLine()) {
				result += input.nextLine() + "\n";
			}
			result = command + "\n" + result; // 加上命令本身，打印出来
			log.info("ExecScript-------->run----------->SH执行结果:{}", result);
		}
		finally {
			if (input != null) {
				input.close();
			}
			if (process != null) {
				process.destroy();
			}
		}
		return result;
	}

	public static String run(String[] command, File file, long timeOut) throws IOException {
		log.info("ExecScript-------->run----------->{}:{}", command, timeOut);
		Scanner input = null;
		String result = "";
		Process process = null;
		try {
			process = Runtime.getRuntime().exec(command, null, file);
			try {
				// 等待命令执行完成
				process.waitFor(timeOut, TimeUnit.SECONDS);
			}
			catch (InterruptedException e) {
				log.info("ExecScript-------->run----------->异常:", e);
				return "";
			}
			InputStream is = process.getInputStream();
			input = new Scanner(is);
			while (input.hasNextLine()) {
				result += input.nextLine() + "\n";
			}
			result = command + "\n" + result; // 加上命令本身，打印出来
			log.info("ExecScript-------->run----------->SH执行结果:{}", result);
		}
		finally {
			if (input != null) {
				input.close();
			}
			if (process != null) {
				process.destroy();
			}
		}
		return result;
	}

	public static String run(String[] command, long timeOut) throws IOException {
		log.info("ExecScript-------->run----------->{}:{}", command, timeOut);
		Scanner input = null;
		String result = "";
		Process process = null;
		try {
			process = Runtime.getRuntime().exec(command);
			try {
				// 等待命令执行完成
				process.waitFor(timeOut, TimeUnit.SECONDS);
			}
			catch (InterruptedException e) {
				log.info("ExecScript-------->run----------->异常:", e);
				return "";
			}
			InputStream is = process.getInputStream();
			input = new Scanner(is);
			while (input.hasNextLine()) {
				result += input.nextLine() + "\n";
			}
			result = command + "\n" + result; // 加上命令本身，打印出来
			log.info("ExecScript-------->run----------->SH执行结果:{}", result);
		}
		finally {
			if (input != null) {
				input.close();
			}
			if (process != null) {
				process.destroy();
			}
		}
		return result;
	}

}
